# -*- coding:utf-8 -*-
from utils.get_keywords import GetKeywords
import pytest
from exceptions.Custom_exception import *
import logging

class BaseAsserts(object):
    """
    封装基础的断言内容
    包括
        状态码断言，code码断言，字符串断言，字符类型断言，接口响应时间断言
    """

    @staticmethod
    def status_code_assert(status_code, result):
        """
        返回状态码断言
        :param status_code: 预期状态码
        :param result:
        :return:
        """
        try:
            return result['status_code'] == status_code
        except AssertionError:
            return False

    @staticmethod
    def data_code_assert(code, result):
        """
        返回code码进行断言
        :param code: 预期code码
        :param result:
        :return:
        """
        try:
            return GetKeywords.get_keyword(result,"code") == int(code)
        except AssertionError:
            return False

    @staticmethod
    def str_assert(check_name, result):
        """
        判断内容是否存在
        :param check_name:预期结果
        :param result: 实际结果
        :return:
        """
        try:
            return str(result).__contains__(str(check_name))
        except AssertionError:
            return False

    @staticmethod
    def type_assert(check_name, check_type, name_index, result):
            """
            进行类型断言
            :param check_name: 需要在json内查找的内容
            :param check_type: 预期断言类型
            :param name_index: 内容索引
            :param result:
            :return:
            """
            try:
                check_value = GetKeywords.get_keyword_index(result,check_name,name_index)
            except Exception:
                ErrorMsg = ['类型参数提取失败', f'断言内容：{check_name}在返回结果{result}内找不到,请检查断言是否正确']
                raise AssertionAnomaly(title=ErrorMsg[0], content=ErrorMsg[1])
            else:
                return isinstance(check_value, eval(check_type))


    @staticmethod
    def response_time_assert(result,expect_time=100):
        """
        响应时间断言
        :param result: 响应结果
        :param expect_time: 预期响应时间 单位：ms  默认100ms
        :return:
        """
        try:
            if GetKeywords.get_keyword(result,"response_time") > expect_time:
                return False
            else:
                return True
        except Exception:
            return False


class MainAsserts(BaseAsserts):
    """
    断言主类，继承BaseAsserts
    获得断言的各种方法
    """

    def __init__(self,checks,res):
        self.checks = checks
        self.res = res

    def main_assert(self):
        """
        多重断言主逻辑
        :return:
        """
        for key,value in self.checks.items():
            if "status_code" == key:
                logging.info(f"3.HTTP状态码断言: 实际结果({self.res['status_code']}) == 预期结果({self.checks['status_code']})")
                pytest.assume(self.status_code_assert(self.checks["status_code"],self.res))
            if "code" == key:
                logging.info(f"3.HTTP code码断言: 实际结果({GetKeywords.get_keyword(self.res,'code')}) == 预期结果({self.checks['code']})")
                pytest.assume(self.data_code_assert(self.checks["code"],self.res))
            if "str" == key:
                for check_name in self.checks["str"]:
                    logging.info(f"3.HTTP 字符串断言: 实际结果({self.res}) == 预期结果({check_name})")
                    pytest.assume(self.str_assert(check_name,self.res))

            if "type" == key:
                for check_type in self.checks["type"]:
                    logging.info(f"3.HTTP 字符类型断言: 实际结果({type(GetKeywords.get_keyword_index(self.res,check_type['check_name'],check_type['name_index']))}) == 预期结果({check_type['check_type']})")

                    pytest.assume(self.type_assert(check_type["check_name"],check_type["check_type"],
                                                   check_type['name_index'],self.res))
            if "time" == key:
                logging.info(f"3.HTTP 响应时间断言: 实际结果({GetKeywords.get_keyword(self.res,'response_time')}) < 预期结果({self.checks['time']})")
                pytest.assume(self.response_time_assert(self.res,self.checks["time"]))

